# -*- coding: utf-8 -*-

import numpy as np
import sympy

# CHARACTER TABLE DATA

pi, i = sympy.pi, sympy.I
c72, c144 = sympy.cos(72 * (pi / 180)), sympy.cos(144 * (pi / 180))
r2, r3 = sympy.sqrt(2), sympy.sqrt(3)
pr5, nr5 = (1 + sympy.sqrt(5)) / 2,  (1 - sympy.sqrt(5)) / 2
E3, E3_ = sympy.exp(2 * pi * i / 3), sympy.exp(-2 * pi * i / 3)
E5, E5_ = sympy.exp(2 * pi * i / 5), sympy.exp(-2 * pi * i / 5)
E6, E6_ = sympy.exp(pi * i / 3), sympy.exp(-pi * i / 3)
E7, E7_ = sympy.exp(2 * pi * i / 7), sympy.exp(-2 * pi * i / 7)
E8, E8_ = sympy.exp(pi * i / 4), sympy.exp(-pi * i / 4)
c5, c5_ = 1 + 2 * sympy.cos(2 * sympy.pi / 5), 1 + 2 * sympy.cos(4 * sympy.pi / 5)
c7 = 1 + 2 * sympy.cos(2 * sympy.pi / 7)
c8, c8_ = 1 + 2 * sympy.cos(2 * sympy.pi / 8), 1 + 2 * sympy.cos(6 * sympy.pi / 8)
c27, c37 = 1 + 2 * sympy.cos(2 * pi * 2 / 7), 1 + 2 * sympy.cos(2 * pi * 3 / 7)
s5, s35 = -1 + 2 * sympy.cos(2 * pi / 5), -1 + 2 * sympy.cos(2 * pi * 3 / 5)
s12, s512 = -1 + 2 * sympy.cos(2 * pi / 12), -1 + 2 * sympy.cos(2 * pi * 5 / 12)

# body of character tables
tables = {'c1': np.array([1]),
          'cs': np.array([[1, 1],
                          [1,-1]]),
          'ci': np.array([[1, 1],
                          [1,-1]]),
          'c2': np.array([[1, 1],
                          [1,-1]]),
          'c3': np.array([[1, 1, 1],
                          [1, E3, E3_],
                          [1, E3_, E3]]),
          'c4': np.array([[1, 1, 1, 1],
                          [1,-1, 1,-1],
                          [1, i, -1, -i],
                          [1, -i, -1, i]]),
          'c5': np.array([[1, 1, 1, 1, 1],
                          [1, E5, E5**2, E5_**2, E5_],
                          [1, E5_, E5_**2, E5**2, E5],
                          [1, E5**2, E5_, E5, E5_**2],
                          [1, E5_**2, E5, E5_, E5**2]]),
          'c6': np.array([[1, 1, 1, 1, 1, 1],
                          [1,-1, 1,-1, 1,-1],
                          [1, E6, -E6_, -1, -E6, E6_],
                          [1, E6_, -E6, -1, -E6_, E6],
                          [1, -E6_, -E6, 1, -E6_, -E6],
                          [1, -E6, -E6_, 1, -E6, -E6_]]),
          'c7': np.array([[1, 1, 1, 1, 1, 1, 1],
                          [1, E7, E7**2, E7**3, E7_**3, E7_**2, E7_],
                          [1, E7_, E7_**2, E7_**3, E7**3, E7**2, E7],
                          [1, E7**2, E7_**3, E7_, E7, E7**3, E7_**2],
                          [1, E7_**2, E7**3, E7, E7_, E7_**3, E7**2],
                          [1, E7**3, E7_, E7**2, E7_**2, E7, E7_**3],
                          [1, E7_**3, E7, E7_**2, E7**2, E7_, E7**3]]),
          'c8': np.array([[1, 1, 1, 1, 1, 1, 1, 1],
                          [1,-1, 1, 1, 1,-1,-1,-1],
                          [1, E8, i, -1, -i, -E8_, -E8, E8_],
                          [1, E8_, -i, -1, i, -E8, -E8_, E8],
                          [1, i, -1, 1, -1, -i, i, -i],
                          [1, -i, -1, 1, -1, i, -i, i],
                          [1, -E8, i, -1, -i, E8_, E8, -E8_],
                          [1, -E8_, -i, -1, i, E8, E8_, -E8_]]),
          'd2': np.array([[1, 1, 1, 1],
                          [1, 1,-1,-1],
                          [1,-1, 1,-1],
                          [1,-1,-1, 1]]),
          'd3': np.array([[1, 1, 1],
                          [1, 1,-1],
                          [2,-1, 0]]),
          'd4': np.array([[1, 1, 1, 1, 1],
                          [1, 1, 1,-1,-1],
                          [1,-1, 1, 1,-1],
                          [1,-1, 1,-1, 1],
                          [2, 0,-2, 0, 0]]),
          'd5': np.array([[1, 1, 1, 1],
                          [1, 1, 1,-1],
                          [2, 2*c72, 2*c144, 0],
                          [2, 2*c144, 2*c72, 0]]),
          'd6': np.array([[1, 1, 1, 1, 1, 1],
                          [1, 1, 1, 1,-1,-1],
                          [1,-1, 1,-1, 1,-1],
                          [1,-1, 1,-1,-1, 1],
                          [2, 1,-1,-2, 0, 0],
                          [2,-1,-1, 2, 0, 0]]),
          'c2v': np.array([[1, 1, 1, 1],
                           [1, 1,-1,-1],
                           [1,-1, 1,-1],
                           [1,-1,-1, 1]]),
          'c3v': np.array([[1, 1, 1],
                           [1, 1,-1],
                           [2,-1, 0]]),
          'c4v': np.array([[1, 1, 1, 1, 1],
                           [1, 1, 1,-1,-1],
                           [1,-1, 1, 1,-1],
                           [1,-1, 1,-1, 1],
                           [2, 0,-2, 0, 0]]),
          'c5v': np.array([[1, 1, 1, 1], [1, 1, 1,-1],
                           [2, 2*c72, 2*c144, 0], [2, 2*c144, 2*c72, 0]]),
          'c6v': np.array([[1, 1, 1, 1, 1, 1], [1, 1, 1, 1,-1,-1],
                           [1,-1, 1,-1, 1,-1], [1,-1, 1,-1,-1, 1],
                           [2, 1,-1,-2, 0, 0], [2,-1,-1, 2, 0, 0]]),
          'c2h': np.array([[1, 1, 1, 1], [1,-1, 1,-1],
                           [1, 1,-1,-1], [1,-1,-1, 1]]),
          'c3h': np.array([[1, 1, 1, 1, 1, 1],
                           [1, E3, E3_, 1, E3, E3_],
                           [1, E3_, E3, 1, E3_, E3],
                           [1, 1, 1,-1,-1,-1],
                           [1, E3, E3_,-1,-E3,-E3_],
                           [1, E3_, E3,-1,-E3_,-E3]]),
          'c4h': np.array([[1, 1, 1, 1, 1, 1, 1, 1],
                           [1,-1, 1,-1, 1,-1, 1,-1],
                           [1, i, -1, -i, 1, i, -1, -i],
                           [1, -i, -1, i, 1, -i, -1, i],
                           [1, 1, 1, 1,-1,-1,-1,-1],
                           [1, -1, 1,-1,-1, 1,-1, 1],
                           [1, i, -1, -i, -1, -i, 1, i],
                           [1, -i, -1, i, -1, i, 1, -i]]),
          'c5h': np.array([[1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
                           [1, E5, E5**2, E5_**2, E5_, 1, E5, E5**2, E5_**2, E5_],
                           [1, E5_, E5_**2, E5**2, E5, 1, E5_, E5_**2, E5**2, E5],
                           [1, E5**2, E5_, E5, E5_**2, 1, E5**2, E5_, E5, E5_**2],
                           [1, E5_**2, E5, E5_, E5**2, 1, E5_**2, E5, E5_, E5**2],
                           [1, 1, 1, 1, 1, -1, -1, -1, -1, -1],
                           [1, E5, E5**2, E5_**2, E5_,-1,-E5,-E5**2,-E5_**2,-E5_],
                           [1, E5_, E5_**2, E5**2, E5,-1,-E5_,-E5_**2,-E5**2,-E5],
                           [1, E5**2, E5_, E5, E5_**2,-1,-E5**2,-E5_,-E5,-E5_**2],
                           [1, E5_**2, E5, E5_, E5**2,-1,-E5_**2,-E5,-E5_,-E5**2]]),
          'c6h': np.array([[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
                           [1,-1, 1,-1, 1,-1, 1,-1, 1,-1, 1,-1],
                           [1, E3, -E3_, -1, -E3, E3_, 1, E3, -E3_, -1, -E3, E3_],
                           [1, E3_, -E3, -1, -E3_, E3, 1, E3_, -E3, -1, -E3_, E3],
                           [1, -E3_, -E3, 1, -E3_, -E3, 1, -E3_, -E3, 1, -E3_, -E3],
                           [1, -E3, -E3_, 1, -E3, -E3_, 1, -E3, -E3_, 1, -E3, -E3_],
                           [1, 1, 1, 1, 1, 1,-1,-1,-1,-1,-1,-1],
                           [1,-1, 1,-1, 1,-1,-1, 1,-1, 1,-1, 1],
                           [1, E3, -E3_, -1, -E3, E3_, -1, -E3, E3_, 1, E3, -E3_],
                           [1, E3_, -E3, -1, -E3_, E3, -1, -E3_, E3, 1, E3_, -E3],
                           [1, -E3_, -E3, 1, -E3_, -E3,-1, E3_, E3, -1, E3_, E3],
                           [1, -E3, -E3_, 1, -E3, -E3_,-1, E3, E3_,-1, E3, E3_]]),
          'd2d': np.array([[1, 1, 1, 1, 1],
                           [1, 1, 1,-1,-1],
                           [1,-1, 1, 1,-1],
                           [1,-1, 1,-1, 1],
                           [2, 0,-2, 0, 0]]),
          'd3d': np.array([[1, 1, 1, 1, 1, 1],
                           [1, 1,-1, 1, 1,-1],
                           [2,-1, 0, 2,-1, 0],
                           [1, 1, 1,-1,-1,-1],
                           [1, 1,-1,-1,-1, 1],
                           [2,-1, 0,-2, 1, 0]]),
          'd4d': np.array([[1, 1, 1, 1, 1, 1, 1],
                           [1, 1, 1, 1, 1,-1,-1],
                           [1,-1, 1,-1, 1, 1,-1],
                           [1,-1, 1,-1, 1,-1, 1],
                           [2,r2, 0,-r2,-2,0, 0],
                           [2, 0,-2, 0, 2, 0, 0],
                           [2,-r2,0,r2,-2, 0, 0]]),
          'd5d': np.array([[1, 1, 1, 1, 1, 1, 1, 1,],
                           [1, 1, 1,-1, 1, 1, 1,-1],
                           [2, 2*c72, 2*c144, 0, 2, 2*c72, 2*c144, 0],
                           [2, 2*c144, 2*c72, 0, 2, 2*c144, 2*72, 0],
                           [1, 1, 1, 1,-1,-1,-1,-1],
                           [1, 1, 1,-1,-1,-1,-1, 1],
                           [2, 2*c72, 2*c144, 0,-2,-2*c72,-2*c144, 0],
                           [2, 2*c144, 2*c72, 0,-2,-2*c144,-2*72, 0]]),
          'd6d': np.array([[1, 1, 1, 1, 1, 1, 1, 1, 1],
                           [1, 1, 1, 1, 1, 1, 1,-1,-1],
                           [1,-1, 1,-1, 1,-1, 1, 1,-1],
                           [1,-1, 1,-1, 1,-1, 1,-1, 1],
                           [2,r3, 1, 0,-1,-r3,-2,0, 0],
                           [2, 1,-1,-2,-1, 1, 2, 0, 0],
                           [2, 0,-2, 0, 2, 0,-2, 0, 0],
                           [2,-1,-1, 2,-1,-1, 2, 0, 0],
                           [2,-r3,1, 0,-1,r3,-2, 0, 0]]),
          'd2h': np.array([[1, 1, 1, 1, 1, 1, 1, 1],
                           [1, 1,-1,-1, 1, 1,-1,-1],
                           [1,-1, 1,-1, 1,-1, 1,-1],
                           [1,-1,-1, 1, 1,-1,-1, 1],
                           [1, 1, 1, 1,-1,-1,-1,-1],
                           [1, 1,-1,-1,-1,-1, 1, 1],
                           [1,-1, 1,-1,-1, 1,-1, 1],
                           [1,-1,-1, 1,-1, 1, 1,-1]]),
          'd3h': np.array([[1, 1, 1, 1, 1, 1],
                           [1, 1,-1, 1, 1,-1],
                           [2,-1, 0, 2,-1, 0],
                           [1, 1, 1,-1,-1,-1],
                           [1, 1,-1,-1,-1, 1],
                           [2,-1, 0,-2, 1, 0]]),
          'd4h': np.array([[1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
                           [1, 1, 1,-1,-1, 1, 1, 1,-1,-1],
                           [1,-1, 1, 1,-1, 1,-1, 1, 1,-1],
                           [1,-1, 1,-1, 1, 1,-1, 1,-1, 1],
                           [2, 0,-2, 0, 0, 2, 0,-2, 0, 0],
                           [1, 1, 1, 1, 1,-1,-1,-1,-1,-1],
                           [1, 1, 1,-1,-1,-1,-1,-1, 1, 1],
                           [1,-1, 1, 1,-1,-1, 1,-1,-1, 1],
                           [1,-1, 1,-1, 1,-1, 1,-1, 1,-1],
                           [2, 0,-2, 0, 0,-2, 0, 2, 0, 0]]),
          'd5h': np.array([[1, 1, 1, 1, 1, 1, 1, 1],
                           [1, 1, 1,-1, 1, 1, 1,-1],
                           [2,2*c72,2*c144, 0, 2,2*c72,2*c144, 0],
                           [2,2*c144,2*c72, 0, 2,2*c144,2*c72, 0],
                           [1, 1, 1, 1,-1,-1,-1,-1],
                           [1, 1, 1,-1,-1,-1,-1, 1],
                           [2,2*c72,2*c144, 0,-2,-2*c72,-2*c144, 0],
                           [2,2*c144,2*c72, 0,-2,-2*c144,-2*c72, 0]]),
          'd6h': np.array([[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
                           [1, 1, 1, 1,-1,-1, 1, 1, 1, 1,-1,-1],
                           [1,-1, 1,-1, 1,-1, 1,-1, 1,-1, 1,-1],
                           [1,-1, 1,-1,-1, 1, 1,-1, 1,-1,-1, 1],
                           [2, 1,-1,-2, 0, 0, 2, 1,-1,-2, 0, 0],
                           [2,-1,-1, 2, 0, 0, 2,-1,-1, 2, 0, 0],
                           [1, 1, 1, 1, 1, 1,-1,-1,-1,-1,-1,-1],
                           [1, 1, 1, 1,-1,-1,-1,-1,-1,-1, 1, 1],
                           [1,-1, 1,-1, 1,-1,-1, 1,-1, 1,-1, 1],
                           [1,-1, 1,-1,-1, 1,-1, 1,-1, 1, 1,-1],
                           [2, 1,-1,-2, 0, 0,-2,-1, 1, 2, 0, 0],
                           [2,-1,-1, 2, 0, 0,-2, 1, 1,-2, 0, 0]]),
          'd8h': np.array([[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
                           [1, 1, 1, 1, 1,-1,-1, 1, 1, 1, 1, 1,-1,-1],
                           [1,-1,-1, 1, 1, 1,-1, 1,-1,-1, 1, 1, 1,-1],
                           [1,-1,-1, 1, 1,-1, 1, 1,-1,-1, 1, 1,-1, 1],
                           [2,r2,-r2,0,-2, 0, 0, 2,r2,-r2, 0,-2, 0, 0],
                           [2, 0, 0,-2, 2, 0, 0, 2, 0, 0,-2, 2, 0, 0],
                           [2,-r2,r2,0,-2, 0, 0, 2,-r2,r2, 0,-2, 0, 0],
                           [1, 1, 1, 1, 1, 1, 1,-1,-1,-1,-1,-1,-1,-1],
                           [1, 1, 1, 1, 1,-1,-1, -1,-1,-1,-1,-1, 1, 1],
                           [1,-1,-1, 1, 1, 1,-1,-1, 1, 1,-1,-1,-1, 1],
                           [1,-1,-1, 1, 1,-1, 1,-1, 1, 1,-1,-1, 1,-1],
                           [2,r2,-r2, 0,-2, 0, 0,-2,-r2,r2, 0, 2, 0, 0],
                           [2, 0, 0,-2, 2, 0, 0,-2, 0, 0, 2,-2, 0, 0],
                           [2,-r2, r2, 0,-2, 0, 0,-2,r2,-r2, 0, 2, 0, 0]]),
          's4': np.array([[1, 1, 1, 1],
                          [1,-1, 1,-1],
                          [1, i,-1,-i],
                          [1,-i,-1, i]]),
          's6': np.array([[1, 1, 1, 1, 1, 1],
                          [1, E3, E3_, 1, E3, E3_],
                          [1, E3_, E3, 1, E3_, E3],
                          [1, 1, 1,-1,-1,-1],
                          [1, E3, E3_,-1,-E3,-E3_],
                          [1, E3_, E3,-1,-E3_,-E3]]),
          's8': np.array([[1, 1, 1, 1, 1, 1, 1, 1],
                          [1,-1, 1,-1, 1,-1, 1,-1],
                          [1, E8, i, -E8_, -1, -E8, -i, E8_],
                          [1, E8_,-i, -E8, -1, -E8_, i, E8],
                          [1, i, -1, -i, 1, i, -1, -i],
                          [1, -i, -1, i, 1, -i, -1, i],
                          [1, -E8_,-i, E8, -1, E8_, i, -E8],
                          [1, -E8, i, E8_, -1, E8, -i, -E8_]]),
          't': np.array([[1, 1, 1, 1],
                         [1, E3, E3_, 1],
                         [1, E3_, E3, 1],
                         [3, 0, 0,-1]]),
          'td': np.array([[1, 1, 1, 1, 1],
                          [1, 1, 1,-1,-1],
                          [2,-1, 2, 0, 0],
                          [3, 0,-1, 1,-1],
                          [3, 0,-1,-1, 1]]),
          'th': np.array([[1, 1, 1, 1, 1, 1, 1, 1],
                          [1, 1, 1, 1,-1,-1,-1,-1],
                          [1, E3, E3_, 1, 1, E3, E3_, 1],
                          [1, E3_, E3, 1, 1, E3_, E3, 1],
                          [1, E3, E3_, 1, -1, -E3, -E3_, -1],
                          [1, E3_, E3, 1, -1, -E3_, -E3, -1],
                          [3, 0, 0,-1, 3, 0, 0,-1],
                          [3, 0, 0,-1,-3, 0, 0, 1]]),
          'o': np.array([[1, 1, 1, 1, 1],
                         [1,-1, 1, 1,-1],
                         [2, 0, 2,-1, 0],
                         [3, 1,-1, 0,-1],
                         [3,-1,-1, 0, 1]]),
          'oh': np.array([[1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
                          [1, 1,-1,-1, 1, 1,-1, 1, 1,-1],
                          [2,-1, 0, 0, 2, 2, 0,-1, 2, 0],
                          [3, 0,-1, 1,-1, 3, 1, 0,-1,-1],
                          [3, 0, 1,-1,-1, 3,-1, 0,-1, 1],
                          [1, 1, 1, 1, 1,-1,-1,-1,-1,-1],
                          [1, 1,-1,-1, 1,-1, 1,-1,-1, 1],
                          [2,-1, 0, 0, 2,-2, 0, 1,-2, 0],
                          [3, 0,-1, 1,-1,-3,-1, 0, 1, 1],
                          [3, 0, 1,-1,-1,-3, 1, 0, 1,-1]]),
          'i': np.array([[1, 1, 1, 1, 1],
                         [3, pr5, nr5, 0, -1],
                         [3, nr5, pr5, 0, -1],
                         [4,-1,-1, 1, 0],
                         [5, 0, 0,-1, 1]]),
          'ih': np.array([[1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
                          [3, pr5, nr5, 0,-1, 3,nr5, pr5, 0,-1],
                          [3, nr5, pr5, 0,-1, 3, pr5, nr5, 0,-1],
                          [4,-1,-1, 1, 0, 4,-1,-1, 1, 0],
                          [5, 0, 0,-1, 1, 5, 0, 0,-1, 1],
                          [1, 1, 1, 1, 1,-1,-1,-1,-1,-1],
                          [3, pr5, nr5, 0,-1,-3,-nr5,-pr5, 0, 1],
                          [3, nr5, pr5, 0,-1,-3,-pr5,-nr5, 0, 1],
                          [4,-1,-1, 1, 0,-4, 1, 1,-1, 0],
                          [5, 0, 0,-1, 1,-5, 0, 0, 1,-1]])
}

# coefficients of number of each symmetry operation for each point group
column_coeffs = {'c1': (1,),
                 'cs': (1, 1),
                 'ci': (1, 1),
                 'c2': (1, 1),
                 'c3': (1, 1, 1),
                 'c4': (1, 1, 1, 1),
                 'c5': (1, 1, 1, 1, 1),
                 'c6': (1, 1, 1, 1, 1, 1),
                 'c7': (1, 1, 1, 1, 1, 1, 1),
                 'c8': (1, 1, 1, 1, 1, 1, 1, 1),
                 'c2v': (1, 1, 1, 1),
                 'c3v': (1, 2, 3),
                 'c4v': (1, 2, 1, 2, 2),
                 'c5v': (1, 2, 2, 5),
                 'c6v': (1, 2, 2, 1, 3, 3),
                 'c2h': (1, 1, 1, 1),
                 'c3h': (1, 1, 1, 1, 1, 1),
                 'c4h': (1, 1, 1, 1, 1, 1, 1, 1),
                 'c5h': (1, 1, 1, 1, 1, 1, 1, 1, 1, 1),
                 'c6h': (1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1),
                 'd2': (1, 1, 1, 1),
                 'd3': (1, 2, 3),
                 'd4': (1, 2, 1, 2, 2),
                 'd5': (1, 2, 2, 5),
                 'd6': (1, 2, 2, 1, 3, 3),
                 'd2d': (1, 2, 1, 2, 2),
                 'd3d': (1, 2, 3, 1, 2, 3),
                 'd4d': (1, 2, 2, 2, 1, 4, 4),
                 'd5d': (1, 2, 2, 5, 1, 2, 2, 5),
                 'd6d': (1, 2, 2, 2, 2, 2, 1, 6, 6),
                 'd2h': (1, 1, 1, 1, 1, 1, 1, 1),
                 'd3h': (1, 2, 3, 1, 2, 3),
                 'd4h': (1, 2, 1, 2, 2, 1, 2, 1, 2, 2),
                 'd5h': (1, 2, 2, 5, 1, 2, 2, 5),
                 'd6h': (1, 2, 2, 1, 3, 3, 1, 2, 2, 1, 3, 3),
                 'd8h': (1, 2, 2, 2, 1, 4, 4, 1, 2, 2, 2, 1, 4, 4),
                 's4': (1, 1, 1, 1),
                 's6': (1, 1, 1, 1, 1, 1),
                 's8': (1, 1, 1, 1, 1, 1, 1, 1),
                 't': (1, 4, 4, 3),
                 'td': (1, 8, 3, 6, 6),
                 'th': (1, 4, 4, 3, 1, 4, 4, 3),
                 'o': (1, 6, 3, 8, 6),
                 'oh': (1, 8, 6, 6, 3, 1, 6, 8, 3, 6),
                 'i': (1, 12, 12, 20, 15),
                 'ih': (1, 12, 12, 20, 15, 1, 12, 12, 20, 15)
}

# coefficients of number row for each irreducible representation due to
# imaginary representations
row_coeffs = {'c3': (1, 2),
              'c4': (1, 1, 2),
              'c5': (1, 2, 2),
              'c6': (1, 1, 2, 2),
              'c7': (1, 2, 2, 2),
              'c8': (1, 1, 2, 2, 2),
              'c3h': (1, 2, 1, 2),
              'c4h': (1, 1, 2, 1, 1, 2),
              'c5h': (1, 2, 2, 1, 2, 2),
              'c6h': (1, 1, 2, 2, 1, 1, 2, 2),
              's4': (1, 1, 2),
              's6': (1, 2, 1, 2),
              's8': (1, 1, 2, 2, 2),
              't': (1, 2, 1),
              'th': (1, 1, 2, 2, 1, 1),
}

# symmetry operation column headers for print functions
# Note: D8h has S^3_8 before S_8. See J. Chem. Educ. 84(11), 1882-1884.
headers = {'c1': ('E'),
           'cs': ('E', '\u03C3h'),
           'ci': ('E', 'i'),
           'c2': ('E', 'C\u2082'),
           'c3': ('E', 'C\u2083', 'C\u2083'+'\u00B2'),
           'c4': ('E', 'C\u2084', 'C\u2082', 'C\u2084'+'\u00B3'),
           'c5': ('E', 'C\u2085', 'C\u2085'+'\u00B2', 'C\u2085'+'\u00B3', 'C\u2085'+'\u2074'),
           'c6': ('E', 'C\u2086', 'C\u2083', 'C\u2082', 'C\u2083'+'\u00B2', 'C\u2086'+'\u2075'),
           'c7': ('E', 'C\u2087', 'C\u2087'+'\u00B2', 'C\u2087'+'\u00B3', 'C\u2087'+'\u2074',  'C\u2087'+'\u2075', 'C\u2087'+'\u2076'),
           'c8': ('E', 'C\u2088', 'C\u2084', 'C\u2082', 'C\u2084'+'\u00B3', 'C\u2088'+'\u00B3', 'C\u2088'+'\u2075', 'C\u2088'+'\u2077'),
           'd2': ('E', 'C\u2082(z)', 'C\u2082(y)', 'C\u2082(x)'),
           'd3': ('E', 'C\u2083', 'C\u2082'),
           'd4': ('E', 'C\u2084', 'C\u2082'+'(=C\u2084\u00B2)', 'C\u2082'+'\u2032', 'C\u2082'+'\u2033'),
           'd5': ('E', 'C\u2085', 'C\u2085'+'\u00B2', 'C\u2082'),
           'd6': ('E', 'C\u2086', 'C\u2083', 'C\u2082', 'C\u2082'+'\u2032', 'C\u2082'+'\u2033'),
           'c2v': ('E', 'C\u2082', '\u03C3v', '\u03C3v'+'\u02B9'),
           'c3v': ('E', 'C\u2083', '\u03C3v'),
           'c4v': ('E', 'C\u2084', 'C\u2082', '\u03C3v', '\u03C3d'),
           'c5v': ('E', 'C\u2085', 'C\u2085'+'\u00B2', '\u03C3v'),
           'c6v': ('E', 'C\u2086', 'C\u2083', 'C\u2082', '\u03C3v', '\u03C3d'),
           'c2h': ('E', 'C\u2082', 'i', '\u03C3h'),
           'c3h': ('E', 'C\u2083', 'C\u2083'+'\u00B2', '\u03C3h', 'S\u2083','S\u2083'+'\u2075'),
           'c4h': ('E', 'C\u2084', 'C\u2082', 'C\u2084'+'\u00B3', 'i', 'S\u2084'+'\u00B3', '\u03C3h', 'S\u2084'),
           'c5h': ('E', 'C\u2085', 'C\u2085'+'\u00B2', 'C\u2085'+'\u00B3', 'C\u2085'+'\u2074', '\u03C3h', 'S\u2085', 'S\u2085'+'\u2077',  'S\u2085'+'\u00B3', 'S\u2085'+'\u2079'),
           'c6h': ('E', 'C\u2086', 'C\u2083', 'C\u2082', 'C\u2083'+'\u00B2', 'C\u2086'+'\u2075', 'i', 'S\u2083'+'\u2075', 'S\u2086'+'\u2075', '\u03C3h', 'S\u2086', 'S\u2083'),
           'd2h': ('E', 'C\u2082(z)', 'C\u2082(y)', 'C\u2082(x)', 'i', '\u03C3(xy)', '\u03C3(xz)', '\u03C3(yz)'),
           'd3h': ('E', 'C\u2083', 'C\u2082', '\u03C3h', 'S\u2083', '\u03C3v'),
           'd4h': ('E', 'C\u2084', 'C\u2082', 'C\u2082'+'\u2032', 'C\u2082'+'\u2033', 'i', 'S\u2084', '\u03C3h', '\u03C3v', '\u03C3d'),
           'd5h': ('E', 'C\u2085', 'C\u2085'+'\u00B2', 'C\u2082', '\u03C3h', 'S\u2085', 'S\u2085'+'\u00B3', '\u03C3v'),
           'd6h': ('E', 'C\u2086', 'C\u2083', 'C\u2082', 'C\u2082'+'\u2032', 'C\u2082'+'\u2033', 'i', 'S\u2083', 'S\u2086', '\u03C3h', '\u03C3d', '\u03C3v'),
           'd8h': ('E', 'C\u2088', 'C\u2088'+'\u00B3', 'C\u2084', 'C\u2082', 'C\u2082'+'\u2032', 'C\u2082'+'\u2033', 'i', 'S\u2088'+'\u00B3', 'S\u2088', 'S\u2084', '\u03C3h', '\u03C3d', '\u03C3v'),
           'd2d': ('E', 'S\u2084', 'C\u2082', 'C\u2082'+'\u2032', '\u03C3d'),
           'd3d': ('E', 'C\u2083', 'C\u2082', 'i', 'S\u2086', '\u03C3d'),
           'd4d': ('E', 'S\u2088', 'C\u2084', 'S\u2088'+'\u00B3', 'C\u2082', 'C\u2082'+'\u2032', '\u03C3d'),
           'd5d': ('E', 'C\u2085', 'C\u2085'+'\u00B2', 'C\u2082', 'i', 'S\u2081'+'\u2080'+'\u00B3','S\u2081'+'\u2080', '\u03C3d'),
           'd6d': ('E', 'S\u2081'+'\u2082', 'C\u2086', 'S\u2084', 'C\u2083', 'S\u2081'+'\u2082'+'\u2075', 'C\u2082', 'C\u2082'+'\u2032', '\u03C3d'),
           's4': ('E', 'S\u2084', 'C\u2082', 'S\u2084'+'\u00B3'),
           's6': ('E', 'C\u2083', 'C\u2083'+'\u00B2', 'i', 'S\u2086'+'\u2075', 'S\u2086'),
           's8': ('E', 'S\u2088', 'C\u2084', 'S\u2088'+'\u00B3', 'C\u2082', 'S\u2088'+'\u2075', 'C\u2084'+'\u00B3', 'S\u2088'+'\u2077'),
           't': ('E', 'C\u2083', 'C\u2083'+'\u00B2', 'C\u2082'),
           'th': ('E', 'C\u2083', 'C\u2083'+'\u00B2', 'C\u2082', 'i', 'S\u2086', 'S\u2086'+'\u2075', '\u03C3h'),
           'td': ('E', 'C\u2083', 'C\u2082', 'S\u2084', '\u03C3d'),
           'o': ('E', 'C\u2084','C\u2082'+'(=C\u2084\u00B2)', 'C\u2083', 'C\u2082'),
           'oh': ('E', 'C\u2083', 'C\u2082', 'C\u2084', 'C\u2082'+'(=C\u2084\u00B2)', 'i', 'S\u2084', 'S\u2086', '\u03C3h', '\u03C3d'),
           'i': ('E', 'C\u2085', 'C\u2085'+'\u00B2', 'C\u2083', 'C\u2082'),
           'ih': ('E', 'C\u2085', 'C\u2085'+'\u00B2', 'C\u2083', 'C\u2082', 'i', 'S\u2081'+'\u2080', 'S\u2081'+'\u2080'+'\u00B3', 'S\u2086', '\u03C3')
}

# Mulliken symbols for each irreducible representation for print functions
# and for returning results as dictionary (to_dict=True)
mulliken = {'c1': ('A'),
            'cs': ("A'", 'A"'),
            'ci': ('Ag', 'Au'),
            'c2': ('A', 'B'),
            'c3': ('A', 'E'),
            'c4': ('A', 'B', 'E'),
            'c5': ('A', 'E1', 'E2'),
            'c6': ('A', 'B', 'E1', 'E2'),
            'c7': ('A', 'E1', 'E2', 'E3'),
            'c8': ('A', 'B', 'E1', 'E2', 'E3'),
            'c2v': ('A1', 'A2', 'B1', 'B2'),
            'c3v': ('A1', 'A2', 'E'),
            'c4v': ('A1', 'A2', 'B1', 'B2', 'E'),
            'c5v': ('A1', 'A2', 'E1', 'E2'),
            'c6v': ('A1', 'A2', 'B1', 'B2', 'E1', 'E2'),
            'c2h': ('Ag', 'Bg', 'Au', 'Bu'),
            'c3h': ("A'", "E'", 'A"', 'E"'),
            'c4h': ('Ag', 'Bg', 'Eg', 'Au', 'Bu', 'Eu'),
            'c5h': ("A'", "E'1", "E'2", 'A"', 'E"1', 'E"2'),
            'c6h': ('Ag', 'Bg', 'E1g', 'E2g', 'Au', 'Bu', 'E1u', 'E2u'),
            'd2': ('A', 'B1', 'B2', 'B3'),
            'd3': ('A1', 'A2', 'E'),
            'd4': ('A1', 'A2', 'B1', 'B2', 'E'),
            'd5': ('A1', 'A2', 'E1', 'E2'),
            'd6': ('A1', 'A2', 'B1', 'B2', 'E1', 'E2'),
            'd2d': ('A1', 'A2', 'B1', 'B2', 'E'),
            'd3d': ('A1g', 'A2g', 'Eg', 'A1u', 'A2u', 'Eu'),
            'd4d': ('A1', 'A2', 'B1', 'B2', 'E1', 'E2', 'E3'),
            'd5d': ('A1g', 'A2g', 'E1g', 'E2g', 'A1u', 'A2u', 'E1u', 'E2u'),
            'd6d': ('A1', 'A2', 'B1', 'B2', 'E1', 'E2', 'E3', 'E4', 'E5'),
            'd2h': ('Ag', 'B1g', 'B2g', 'B3g', 'Au', 'B1u', 'B2u', 'B3u'),
            'd3h': ("A'1", "A'2", "E'", 'A"1', 'A"2', 'E"'),
            'd4h': ('A1g', 'A2g', 'B1g', 'B2g', 'Eg', 'A1u', 'A2u', 'B1u', 'B2u', 'Eu'),
            'd5h': ("A'1", "A'2", "E'1", "E'2", 'A"1', 'A"2', 'E"1', 'E"2'),
            'd6h': ('A1g', 'A2g', 'B1g', 'B2g', 'E1g', 'E2g', 'A1u', 'A2u', 'B1u', 'B2u', 'E1u', 'E2u'),
            'd8h': ('A1g', 'A2g', 'B1g', 'B2g', 'E1g', 'E2g', 'E3g', 'A1u', 'A2u', 'B1u', 'B2u', 'E1u', 'E2u', 'E3u'),
            's4': ('A', 'B', 'E'),
            's6': ('Ag', 'Eg', 'Au', 'Eu'),
            's8': ('A', 'B', 'E1', 'E2', 'E3'),
            't': ('A', 'E', 'T'),
            'td': ('A1', 'A2', 'E', 'T1', 'T2'),
            'th': ('Ag', 'Au', 'Eg', 'Eu', 'Tg', 'Tu'),
            'o': ('A1', 'A2', 'E', 'T1', 'T2'),
            'oh': ('A1g', 'A2g', 'Eg', 'T1u', 'T2g', 'A1u', 'A2u', 'Eu', 'T1u', 'T2u'),
            'i': ('A', 'T1', 'T2', 'G', 'H'),
            'ih': ('Ag', 'T1g', 'T2g', 'Gg', 'Hg', 'Au', 'T1u', 'T2u', 'Gu', 'Hu')
}

# number of rotational plus translation modes in each irreducible representations
# used to subtract from all motions to obtain just vibrational modes
# Note: S8 has (Rx, Ry) in E3. See J. Chem. Educ. 84(11), 1882-1884.
rot_trans_modes = {'c1': (0,),
                   'cs': (2, 2),
                   'ci': (2, 2),
                   'c2': (2, 2),
                   'c3': (2, 2),
                   'c4': (2, 0, 2),
                   'c5': (2, 2, 0),
                   'c6': (2, 0, 2, 0),
                   'c7': (2, 2, 0, 0),
                   'c8': (2, 0, 2, 0, 0),
                   'd2': (0, 2, 2, 2),
                   'd3': (0, 2, 2),
                   'd4': (0, 2, 0, 0, 2),
                   'd5': (0, 2, 2, 0),
                   'd6': (0, 2, 0, 0, 2, 0),
                   'c2v': (1, 1, 2, 2),
                   'c3v': (1, 1, 2),
                   'c4v': (1, 1, 0, 0, 2),
                   'c5v': (1, 1, 2, 0),
                   'c6v': (1, 1, 0, 0, 2, 0),
                   'c2h': (1, 2, 1, 2),
                   'c3h': (1, 1, 1, 1),
                   'c4h': (1, 0, 1, 1, 0, 1),
                   'c5h': (1, 1, 0, 1, 1, 0),
                   'c6h': (1, 0, 1, 0, 1, 0, 1, 0),
                   'd2h': (0, 1, 1, 1, 0, 1, 1, 1),
                   'd3h': (0, 1, 1, 0, 1, 1),
                   'd4h': (0, 1, 0, 0, 1, 0, 1, 0, 0, 1),
                   'd5h': (0, 1, 1, 0, 0, 1, 1, 0),
                   'd6h': (0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0),
                   'd8h': (0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0),
                   'd2d': (0, 1, 0, 1, 2),
                   'd3d': (0, 1, 1, 0, 1, 1),
                   'd4d': (0, 1, 0, 1, 1, 0, 1),
                   'd5d': (0, 1, 1, 0, 0, 1, 1, 0),
                   'd6d': (0, 1, 0, 1, 1, 0, 0, 0, 1),
                   's4': (1, 1, 2),
                   's6': (1, 1, 1, 1),
                   's8': (1, 1, 1, 0, 1),
                   't': (0, 0, 2),
                   'th': (0, 0, 0, 0, 1, 1),
                   'td': (0, 0, 0, 1, 1),
                   'o': (0, 0, 0, 2, 0),
                   'oh': (0, 0, 0, 1, 0, 0, 0, 0, 1, 0),
                   'i': (0, 2, 0, 0, 0),
                   'ih': (0, 1, 0, 0, 0, 0, 1, 0, 0, 0)
}

# Indicates whether the irreducible representation is IR active (1) or not (0)
IR_active = {'c1': (0,),
             'cs': (1, 1),
             'ci': (0, 1),
             'c2': (1, 1),
             'c3': (1, 1),
             'c4': (1, 0, 1),
             'c5': (1, 1, 0),
             'c6': (1, 0, 1, 0),
             'c7': (1, 1, 0, 0),
             'c8': (1, 0, 1, 0, 0),
             'd2': (0, 1, 1, 1),
             'd3': (0, 1, 1),
             'd4': (0, 1, 0, 0, 1),
             'd5': (0, 1, 1, 0),
             'd6': (0, 1, 0, 0, 1, 0),
             'c2v': (1, 0, 1, 1),
             'c3v': (1, 0, 1),
             'c4v': (1, 0, 0, 0, 1),
             'c5v': (1, 0, 1, 0),
             'c6v': (1, 0, 0, 0, 1, 0),
             'c2h': (0, 0, 1, 1),
             'c3h': (0, 1, 1, 0),
             'c4h': (0, 0, 0, 1, 0, 1),
             'c5h': (0, 1, 0, 1, 0, 0),
             'c6h': (0, 0, 0, 0, 1, 0, 1, 0),
             'd2h': (0, 0, 0, 0, 0, 1, 1, 1),
             'd3h': (0, 0, 1, 0, 1, 0),
             'd4h': (0, 0, 0, 0, 0, 0, 1, 0, 0, 1),
             'd5h': (0, 0, 1, 0, 0, 1, 0, 0),
             'd6h': (0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0),
             'd8h': (0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0),
             'd2d': (0, 0, 0, 1, 1),
             'd3d': (0, 0, 0, 0, 1, 1),
             'd4d': (0, 0, 0, 1, 1, 0, 0),
             'd5d': (0, 0, 0, 0, 0, 1, 1, 0),
             'd6d': (0, 0, 0, 1, 1, 0, 0, 0, 0),
             's4': (0, 1, 1),
             's6': (0, 0, 1, 1),
             's8': (0, 1, 1, 0, 0),
             't': (0, 0, 1),
             'th': (0, 0, 0, 0, 0, 1),
             'td': (0, 0, 0, 0, 1),
             'o': (0, 0, 0, 1, 0),
             'oh': (0, 0, 0, 0, 0, 0, 0, 0, 1, 0),
             'i': (0, 1, 0, 0, 0),
             'ih': (0, 0, 0, 0, 0, 0, 1, 0, 0, 0)
}

# Indicates whether the irreducible representation is Raman active (1) or not (0)
Raman_active = {'c1': (0,),
                'cs': (1, 1),
                'ci': (1, 0),
                'c2': (1, 1),
                'c3': (1, 1),
                'c4': (1, 1, 1),
                'c5': (1, 1, 1),
                'c6': (1, 0, 1, 1),
                'c7': (1, 1, 1, 0),
                'c8': (1, 0, 1, 1, 0),
                'd2': (1, 1, 1, 1),
                'd3': (1, 0, 1),
                'd4': (1, 0, 1, 1, 1),
                'd5': (1, 0, 1, 1),
                'd6': (1, 0, 0, 0, 1, 1),
                'c2v': (1, 1, 1, 1),
                'c3v': (1, 0, 1),
                'c4v': (1, 0, 1, 1, 1),
                'c5v': (1, 0, 1, 1),
                'c6v': (1, 0, 0, 0, 1, 1),
                'c2h': (1, 1, 0, 0),
                'c3h': (1, 1, 0, 1),
                'c4h': (1, 1, 1, 0, 0, 0),
                'c5h': (1, 0, 1, 0, 1, 0),
                'c6h': (1, 0, 1, 1, 0, 0, 0, 0),
                'd2h': (1, 1, 1, 1, 0, 0, 0, 0),
                'd3h': (1, 0, 1, 0, 0, 1),
                'd4h': (1, 0, 1, 1, 1, 0, 0, 0, 0, 0),
                'd5h': (1, 0, 0, 1, 0, 0, 1, 0),
                'd6h': (1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0),
                'd8h': (1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0),
                'd2d': (1, 0, 1, 1, 1),
                'd3d': (1, 0, 1, 0, 0, 0),
                'd4d': (1, 0, 0, 0, 0, 1, 1),
                'd5d': (1, 0, 1, 1, 0, 0, 0, 0),
                'd6d': (1, 0, 0, 0, 0, 1, 0, 0, 1),
                's4': (1, 1, 1),
                's6': (1, 1, 0, 0),
                's8': (1, 0, 0, 1, 1),
                't': (1, 1, 1),
                'th': (1, 0, 1, 0, 1, 0),
                'td': (1, 0, 1, 0, 1),
                'o': (1, 0, 1, 0, 1),
                'oh': (1, 0, 1, 0, 1, 0, 0, 0, 0, 0),
                'i': (1, 0, 0, 0, 1),
                'ih': (1, 0, 0, 0, 1, 0, 0, 0, 0, 0)
}

# Masks to remove degenerate values from imaginary degenerate irreducible
# representations allowing us to avoid the "doubling problem"
# (https://doi.org/10.1021/ed070p17). This occurs due to two complex conjugate
# representations (in curly brackets in some character tables) both returning
# the number of irreducible representations. These masks remove one result
# when applicable to avoid a double contribution to the result.
masks = {'c1': (1,),
         'cs': (1, 1),
         'ci': (1, 1),
         'c2': (1, 1),
         'c3': (1, 1, 0),
         'c4': (1, 1, 1, 0),
         'c5': (1, 1, 0, 1, 0),
         'c6': (1, 1, 1, 0, 1, 0),
         'c7': (1, 1, 0, 1, 0, 1, 0),
         'c8': (1, 1, 1, 0, 1, 0, 1, 0),
         'd2': (1, 1, 1, 1),
         'd3': (1, 1, 1),
         'd4': (1, 1, 1, 1, 1),
         'd5': (1, 1, 1, 1),
         'd6': (1, 1, 1, 1, 1, 1),
         'c2v': (1, 1, 1, 1),
         'c3v': (1, 1, 1),
         'c4v': (1, 1, 1, 1, 1),
         'c5v': (1, 1, 1, 1),
         'c6v': (1, 1, 1, 1, 1, 1),
         'c2h': (1, 1, 1, 1),
         'c3h': (1, 1, 0, 1, 1, 0),
         'c4h': (1, 1, 1, 0, 1, 1, 1, 0),
         'c5h': (1, 1, 0, 1, 0, 1, 1, 0, 1, 0),
         'c6h': (1, 1, 1, 0, 1, 0, 1, 1, 1, 0, 1, 0),
         'd2h': (1, 1, 1, 1, 1, 1, 1, 1),
         'd3h': (1, 1, 1, 1, 1, 1),
         'd4h': (1, 1, 1, 1, 1, 1, 1, 1, 1, 1),
         'd5h': (1, 1, 1, 1, 1, 1, 1, 1),
         'd6h': (1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1),
         'd8h': (1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1),
         'd2d': (1, 1, 1, 1, 1),
         'd3d': (1, 1, 1, 1, 1, 1),
         'd4d': (1, 1, 1, 1, 1, 1, 1),
         'd5d': (1, 1, 1, 1, 1, 1, 1, 1),
         'd6d': (1, 1, 1, 1, 1, 1, 1, 1, 1),
         's4': (1, 1, 1, 0),
         's6': (1, 1, 0, 1, 1, 0),
         's8': (1, 1, 1, 0, 1, 0, 1, 0),
         't': (1, 1, 0, 1),
         'th': (1, 1, 1, 0, 1, 0, 1, 1),
         'td': (1, 1, 1, 1, 1),
         'o': (1, 1, 1, 1, 1),
         'oh': (1, 1, 1, 1, 1, 1, 1, 1, 1, 1),
         'i': (1, 1, 1, 1, 1),
         'ih': (1, 1, 1, 1, 1, 1, 1, 1, 1, 1)
}


# Per atom contributions to all motions calculated using R = x + 2 * cos(2*pi*k/n)
# where x is +1 for proper rotations and E and -1 for inversions, improper rotations,
# and reflections, and k and n are integers in a C^k_n rotation. Note: E is
# equivalent to a C_1, a reflection is equal to an S_1, and an i is equivalent
# to an S_2. See Vincent, Alan Molecular Symmetry and Group Theory, Wiley,
# 1998, pp. 131.
atom_contribution = {'c1': [3],
                     'cs': [3, 1],
                     'ci': [3, -3],
                     'c2': [3, -1],
                     'c3': [3, 0, 0],
                     'c4': [3, 1, -1, 1],
                     'c5': [3, c5, c5_, c5_, c5],
                     'c6': [3, 2, 0, -1, 0, 2],
                     'c7': [3, c7, c27, c37, c37, c27, c7],
                     'c8': [3, c8, 1, -1, 1, c8_, c8_, c8],
                     'd2': [3, -1, -1, -1],
                     'd3': [3, 0, -1],
                     'd4': [3, 1, -1, -1, -1],
                     'd5': [3, c5, c5_, -1],
                     'd6': [3, 2, 0, -1, -1, -1],
                     'c2v': [3, -1, 1, 1],
                     'c3v': [3, 0, 1],
                     'c4v': [3, 1, -1, 1, 1],
                     'c5v': [3, c5, c5_, 1],
                     'c6v': [3, 2, 0, -1, 1, 1],
                     'c2h': [3, -1, -3, 1],
                     'c3h': [3, 0, 0, 1, -2, -2],
                     'c4h': [3, 1, -1, 1, -3, -1, 1, -1],
                     'c5h': [3, c5, c5_, c5_, c5, 1, s5, -c5 - 1, -c5 - 1, s5],
                     'c6h': [3, 2, 0, -1, 0, 2, -3, -2, 0, 1, 0, -2],
                     'd2h': [3, -1, -1, -1, -3, 1, 1, 1],
                     'd3h': [3, 0, -1, 1, -2, 1],
                     'd4h': [3, 1, -1, -1, -1, -3, -1, 1, 1, 1],
                     'd5h': [3, c5, c5_, -1, 1, s5, s35, 1],
                     'd6h': [3, 2, 0, -1, -1, -1, -3, -2, 0, 1, 1, 1],
                     'd8h': [3, c8, c8_, 1, -1, -1, -1, -3, -c8_, -c8, -1, 1, 1, 1],
                     'd2d': [3, -1, -1, -1, 1],
                     'd3d': [3, 0, -1, -3, 0, 1],
                     'd4d': [3, -c8_, 1, -c8, -1, -1, 1],
                     'd5d': [3, c5, c5_, -1, -3, -c5, -c5_, 1],
                     'd6d': [3, s12, 2, -1, 0, s512, -1, -1, 1],
                     's4': [3, -1, -1, -1],
                     's6': [3, 0, 0, -3, 0, 0],
                     's8': [3, -c8_, 1, -c8, -1, -c8, 1, -c8_],
                     't': [3, 0, 0, -1],
                     'th': [3, 0, 0, -1, -3, 0, 0, 1],
                     'td': [3, 0, -1, -1, 1],
                     'o': [3, 1, -1, 0, -1],
                     'oh': [3, 0, -1, 1, -1, -3, -1, 0, 1, 1],
                     'i': [3, c5, c5_, 0, -1],
                     'ih': [3, c5, c5_, 0, -1, -3, -c5_, -c5, 0, 1]
 }


# Symmetry functions for each point group from character table used to
# calculate symmetry adapted linear combinations.
symmetry_func_dict = {'c1': (1),
                      'cs': (('x', 'y', 'x**2', 'y**2', 'z**2', 'x*y'), ('z', 'y*z', 'x*z')),
                      'ci': (('x**2', 'y**2', 'z**2', 'x*y', 'x*z', 'y*x'), ('x', 'y', 'z')),
                      'c2': (('z', 'x**2', 'y**2', 'z**2', 'x*y'), ('x', 'y', 'y*z', 'x*z')),
                      'c3': (('z', 'x**2+y**2', 'z**2'), ('x', 'y', 'x**2-y**2', 'x*y', 'y*z', 'x*z')),
                      'c4': (('z', 'x**2+y**2', 'z**2'), ('x**2-y**2', 'x*y'), ('x', 'y', 'y*z', 'x*z')),
                      'c5': (('z', 'x**2+y**2', 'z**2'), ('x', 'y', 'y*z', 'x*z'), ('x**2-y**2', 'x*y')),
                      'c6': (('z', 'x**2+y**2', 'z**2'), 0, ('x', 'y', 'y*z', 'x*z'), ('x**2-y**2', 'x*y')),
                      'c7': (('z', 'x**2+y**2', 'z**2'), ('x', 'y', 'y*z', 'x*z'), ('x**2-y**2', 'x*y'), 0),
                      'c8': (('z', 'x**2+y**2', 'z**2'), 0, ('x', 'y', 'y*z', 'x*z'), ('x**2-y**2', 'x*y'), 0),
                      'd2': (('x**2', 'y**2', 'z**2'), ('z', 'x*y'), ('y', 'x*z'), ('x', 'y*z')),
                      'd3': (('x**2+y**2', 'z**2'), ('z',), ('x', 'y', 'x**2-y**2', 'x*y', 'x*z', 'y*z')),
                      'd4': (('x**2+y**2', 'z**2'), ('z',), ('x**2-y**2',), ('x*y',), ('x', 'y', 'x*z', 'y*z')),
                      'd5': (('x**2+y**2', 'z**2'), ('z',), ('x', 'y', 'x*z', 'y*z'), ('x**2-y**2', 'x*y')),
                      'd6': (('x**2+y**2', 'z**2'), ('z',), 0, 0, ('x', 'y', 'x*z', 'y*z'), ('x**2-y**2', 'x*y')),
                      'c2v': (('z', 'x**2', 'y**2', 'z**2'), ('x*y',), ('x', 'x*z'), ('y', 'y*z')),
                      'c3v': (('z', 'x**2+y**2', 'z**2'), 0, ('x', 'y', 'x**2-y**2', 'x*y', 'x*z', 'y*z')),
                      'c4v': (('z', 'x**2+y*2', 'z**2'), 0, ('x**2-y**2',), ('x*y',), ('x', 'y', 'x*z', 'y*z')),
                      'c5v': (('z', 'x**2+y**2', 'z**2'), 0, ('x', 'y', 'x*z', 'y*z'), ('x**2-y**2', 'x*y')),
                      'c6v': (('z', 'x**2+y**2', 'z**2'), 0, 0, 0, ('x', 'y', 'x*z', 'y*z'), ('x**2-y**2', 'x*y')),
                      'c2h': (('x**2', 'y**2', 'z**2', 'x*y'), ('x*z', 'y*z'), ('z',), ('x', 'y')),
                      'c3h': (('x**2+y**2', 'z**2'), ('x', 'y', 'x**2-y**2', 'x*y'), ('z',), ('x*z', 'y*z')),
                      'c4h': (('x**2+y**2', 'z**2'), ('x**2-y**2', 'x*y'), ('x*z', 'y*z'), ('z',), 0, ('x', 'y')),
                      'c5h': (('x**2+y**2', 'z**2'), ('x', 'y'), ('x**2-y**2', 'x*y'), ('z',), ('x*z', 'y*z'), 0),
                      'c6h': (('x**2+y**2', 'z**2'), 0, ('x*z', 'y*z'), ('x**2-y**2', 'x*y'), ('z',), 0, ('x', 'y'), 0),
                      'd2h': (('x**2', 'y**2', 'z**2'), ('x*y',), ('x*z',), ('y*z',), 0, ('z',), ('y',), ('x',)),
                      'd3h': (('x**2+y**2', 'z**2'), 0, ('x', 'y', 'x**2-y**2', 'x*y'), 0, ('z',), ('x*z', 'y*z')),
                      'd4h': (('x**2+y**2', 'z**2'), 0, ('x**2-y**2',), ('x*y',), ('x*z', 'y*z'), 0, ('z',), 0, 0, ('x', 'y')),
                      'd5h': (('x**2+y**2', 'z**2'), 0, ('x', 'y'), ('x**2-y**2', 'x*y'), 0, ('z',), ('x*z', 'y*z'), 0),
                      'd6h': (('x**2+y**2', 'z**2'), 0, 0, 0, ('x*z', 'y*z'), ('x**2-y**2', 'x*y'), 0, ('z',), 0, 0, ('x', 'y'), 0),
                      'd8h': (('x**2+y**2', 'z**2'), 0, 0, 0, ('x*z', 'y*z'), ('x**2-y**2', 'x*y'), 0, 0, ('z',), 0, 0, ('x', 'y'), 0, 0),
                      'd2d': (('x**2+y**2', 'z**2'), 0, ('x**2-y**2',), ('z', 'x*y'), ('x', 'y', 'x*z', 'y*z')),
                      'd3d': (('x**2+y**2', 'z**2'), 0, ('x**-y**2', 'x*y', 'x*z', 'y*z'), 0, ('z',), ('x', 'y')),
                      'd4d': (('x**2+y**2', 'z**2'), 0, 0, ('z',), ('x', 'y'), ('x**2-y**2', 'x*y'), ('x*z', 'y*z')),
                      'd5d': (('x**2+y**2', 'z**2'), 0, ('x*z', 'y*z'), ('x**2-y**2', 'x*y'), 0, ('z',), ('x', 'y'), 0),
                      'd6d': (('x**2+y**2', 'z**2'), 0, 0, ('z',), ('x', 'y'), ('x**2-y**2', 'x*y'), 0, 0, ('x*z', 'y*z')),
                      's4': (('x**2+y**2', 'z**2'), ('z', 'x**2-y**2', 'x*y'), ('x', 'y', 'x*z', 'y*z')),
                      's6': (('x**2+y**2', 'z**2'), ('x**2-y**2', 'x*y', 'x*z', 'y*z'), ('z',), ('x', 'y')),
                      's8': (('x**2+y**2', 'z**2'), ('z',), ('x', 'y'), ('x**2-y**2', 'x*y'), ('x*z', 'y*z')),
                      't': (('x**2+y**2', 'z**2'), ('2*z**2-x**2-y**2', 'x**2-y**2'), ('x', 'y', 'z', 'x*y', 'x*z', 'y*z')),
                      'th': (('x**2+y**2+z**2',), 0, ('2*z**2-x**2-y**2', 'x**2-y**2'), 0, ('x*y', 'x*z', 'y*z'), ('x', 'y', 'z')),
                      'td': (('x**2+y**2+z**2',), 0, ('2*z**2-x**2-y**2', 'x**2-y**2'), 0, ('x', 'y', 'z', 'x*y', 'x*z', 'y*z')),
                      'o': (('x**2+y**2+z**2',), 0, ('2*z**2-x**2-y**2', 'x**2-y**2'), ('x', 'y', 'z'), ('x*y', 'x*z', 'y*z')),
                      'oh': (('x**2+y**2+z**2',), 0, ('2*z**2-x**2-y**2', 'x**2-y**2'), 0, ('x*y', 'x*z', 'y*z'), 0, 0, 0, ('x', 'y', 'z'), 0),
                      'i': (('x**2+y**2+z**2',), ('x', 'y', 'z'), 0, 0, ('x*y', 'x*z', 'y*z', 'x**2-y**2', '2*z**2-x**2-y**2')),
                      'ih': (('x**2+y**2+z**2',), 0, 0, 0, ('2*z**2-x**2-y**2', 'x**2-y**2', 'x*y', 'x*z', 'y*z'), 0, ('x', 'y', 'z'), 0, 0, 0)
}
